<?php

/**
 * NOTICE OF LICENSE
 *
 * THIS SOURCE FILE IS PART OF EVEBIT'S PRIVATE PROJECT.
 * 
 * DO NOT USE THIS FILE IN OTHER PLACE.
 *
 * @category    EveBit_Library
 * @package     Application
 * @author      Cheng Wei <berlios.o@gmail.com>
 * @version     $$Id: Session.php 701 2011-05-07 09:50:17Z ma.rongliang $$
 * @copyright   Copyright (c) 2008 Evebit Inc. China (http://www.evebit.com)
 */

/**
 * Global Session
 * 
 * 1, get current locale (language)
 * <code>
 * $locale = $session->getLocale();
 * </code>
 * 
 * 2, set current locale
 * <code>
 * $session->setLocale('en-US');
 * </code>
 * 
 * 3, send message to next page
 * You could use $session->addMessage() to sotre some message.
 * They will been shown on the next page, then clean it automatically.
 * <code>
 * $session->addMessage("notice", "this is notice");
 * $session->addError("this is error");
 * $session->addSuccess("this is success message");
 * $session->addNotice("this is notice"); 
 * </code>
 * 
 * 
 * @docinfo
 * 
 * @category    EveBit_Library
 * @package     Application
 * @author      Cheng Wei <berlios.o@gmail.com>
 * @version     $$Id: Session.php 701 2011-05-07 09:50:17Z ma.rongliang $$
 */
class Evebit_Application_Session extends Zend_Session_Namespace {

	/**
	 * Set current account, backend and frontend
	 * 
	 * @param Varien_Object|int $ob
	 * @return Evebit_Application_Session
	 */
	public function setCurrentAccount($ob) {
		$member = Zend_Auth_Storage_Session::MEMBER_DEFAULT;
		if (is_object($ob)) {
			$this->{$member} = $ob->getId();
		} else {
			$this->{$member} = intval($ob);
		}
		return $this;
	}

	/**
	 * Detect default locale
	 * 
	 * @return string
	 */
	public function detectDefaultLocale() {
		$locale = 'en_US';
		
		// $ip = "129.69.210.96"; Germen
		if (!isset($_SERVER['REMOTE_ADDR'])) {
			return $locale;
		}
		
		$ip = $_SERVER['REMOTE_ADDR'];
		
		$localeMap = array('US'=> 'en_US', 'DE'=> 'de_DE', 'DK'=> 'da_DK');
		
		$file = PP . '/../media/GeoIP.dat';
		if (is_file($file)) {
			require_once 'Net/GeoIP.php';
			
			$geo = Net_GeoIP::getInstance($file, Net_GeoIp::STANDARD);
			$countryCode = $geo->lookupCountryCode($ip);
			$geo->close();
			
			if (isset($localeMap[$countryCode])) {
				$locale = $localeMap[$countryCode];
			}
		}
		
		return $locale;
	}

	/**
	 * Get current locale, if not set, detect automatic
	 * 
	 * @return string
	 */
	public function getLocale() {
		if (!isset($this->locale) || !$this->locale) {
			$this->setLocale($this->detectDefaultLocale());
		}
		return $this->locale;
	}

	/**
	 * Set current locale
	 * 
	 * @param string $locale
	 */
	public function setLocale($locale) {
		$this->locale = $locale;
		Zend_Locale::setDefault($locale);
		Zend_Registry::get('Zend_Translate')->getAdapter()->setLocale($locale);
		return $this;
	}

	/**
	 * @var Zend_Translate
	 */
	protected $_translate = null;

	/**
	 * Translate into current locale
	 * 
	 * @param array $msg
	 * @return string
	 */
	public function translate($msg) {
		if (!is_array($msg)) {
			$msg = func_get_args();
		}
		
		$fmt = array_shift($msg);
		$args = $msg;
		
		if (!$this->_translate && Zend_Registry::isRegistered('Zend_Translate')) {
			$this->_translate = Zend_Registry::get('Zend_Translate');
		}
		
		if ($this->_translate) {
			$fmt = $this->_translate->translate($fmt);
		}
		
		if ($args) {
			return vsprintf($fmt, $args);
		} else {
			return $fmt;
		}
	}

	// {{{ messages
	

	/**
	 * @return array
	 */
	public function getMessages() {
		return $this->messages;
	}

	/**
	 * Clear messages
	 */
	public function clearMessages() {
		$this->writeMessage();
		return $this->messages = array();
	}

	/**
	 * Add message
	 * 
	 * @param string|Varien_Object $msg
	 * @param string|null $level
	 */
	public function addMessage($msg, $level = null) {
		if ($msg instanceof Varien_Object) {
			$this->messages[] = $msg;
		} else {
			$this->messages[] = new Varien_Object(array('message'=> $msg, 'level'=> $level));
		}
	}

	/**
	 * Add notice message
	 * 
	 * @param string $msg
	 */
	public function addNotice($msg) {
		$this->addMessage(new Varien_Object(array('message'=> $msg, 'level'=> 'notice')));
		$this->writeMessage('notice', $msg);
	}

	/**
	 * Add success message
	 * 
	 * @param string $msg
	 */
	public function addSuccess($msg) {
		$this->addMessage(new Varien_Object(array('message'=> $msg, 'level'=> 'success')));
		$this->writeMessage('success', $msg);
	}

	/**
	 * Add error message
	 * 
	 * @param string $msg
	 */
	public function addError($msg) {
		$this->addMessage(new Varien_Object(array('message'=> $msg, 'level'=> 'error')));
		$this->writeMessage('error', $msg);
	}
    
	public function writeMessage($type = null, $msg = null){
		if ($type){
			$content = $type.'@@'.$msg;
		}else{
			$content = '';
		}
		$handle = fopen(RP.DS.'application'.DS.'modules'.DS.'blocks'.DS.'frontend-views'.DS.'scripts'.DS.'ajax-get-message.phtml', 'w+');
		fwrite($handle, $content);
		fclose($handle);
	}
	// }}} messages
	

	// {{{ Grid state
	

	/**
	 * init grid state
	 * 
	 * @param string $id
	 * @param array $filters
	 * @param array $orders
	 * @param Zend_Controller_Request_Http $request
	 */
	public function initGrid($id, $filters, $orders, $default) {
		$controller = Zend_Controller_Front::getInstance();
		$request = $controller->getRequest();
		if (!isset($this->grids['id']) || $this->grids['id'] != $id) {
			$this->grids = array(
					'id'=> $id, 
					'filters'=> array(), 
					'orders'=> array(), 
					'sort'=> array(
							'key'=> null, 
							'field'=> isset($orders[@$default['sort']]) ? $orders[$default['sort']] : null, 
							'order'=> isset($default['order']) && $default['order'] == 'desc' ? 'desc' : 'asc'), 
					'pager'=> array(
							'size'=> isset($default['size']) ? $default['size'] : 12, 
							'page'=> 1));
		}
		
		if ($filters) {
			$data = $request->getParam('filter');
			foreach ($filters as $key => $filter) {
				$fields = @($filter['fields']);
				$type = @($filter['type']);
				//$this->grids['filters'][$key]=null;
				if (!isset($this->grids['filters'][$key])) {
					$this->grids['filters'][$key] = array_merge($filter, 
						array('key'=> $key, 'fields'=> $fields, 'type'=> $type, 'data'=> null));
				}
				if (isset($data[$key])) {
					$val = $data[$key];
					switch ($type) {
						case 'int' :
							if (!@$val['from']) {
								unset($val['from']);
							}
							if (!@$val['to']) {
								unset($val['to']);
							}
							if (!$val) {
								$val = null;
							}
							break;
						case 'string' :
							if (!@$val['like']) {
								$val = null;
							}
							break;
						case 'date' :
							if (!@$val['from']) {
								unset($val['from']);
							}
							if (!@$val['to']) {
								unset($val['to']);
							}
							if (!$val) {
								$val = null;
							}
							break;
					}
					$this->grids['filters'][$key]['data'] = $val;
				}
			}
		}
		
		if ($orders) {
			$data = array('key'=> $request->getParam('sort'), 'order'=> $request->getParam('order'));
			if ($data && isset($orders[$data['key']])) {
				$data['field'] = $orders[$data['key']];
				$this->grids['sort'] = $data;
			}
			$this->grids['orders'] = $orders;
		}
		
		$data = intval($request->getParam('PerPage'));
		if ($data) {
			$this->grids['pager']['size'] = $data;
		}
		
		$data = intval($request->getParam('page'));
		if ($data) {
			$this->grids['pager']['page'] = $data;
		}
	
	}

	/**
	 * reset grid filters
	 */
	public function resetGrid() {
		foreach (array_keys($this->grids['filters']) as $key) {
			$this->grids['filters'][$key]['data'] = null;
		}
	}

	/**
	 * fetch grid state 
	 */
	public function getGridState() {
		return $this->grids;
	}

	/**
	 * 
	 * @param Evebit_Model_Mysql_Collection $collection
	 * @param Zend_Paginator $paginator
	 */
	public function applyCollection($collection, $paginator) {
		
		foreach ($this->grids['filters'] as $filter) {
			if ($filter['data']) {
				if (is_array($filter['data'])) {
					$data = $filter['data'];
				} else {
					$data = array('eq'=> $filter['data']);
				}
				
				if (isset($data['like'])) {
					$data['like'] = '%' . $data['like'] . '%';
				}
				if (isset($data['nlike'])) {
					$data['nlike'] = '%' . $data['nlike'] . '%';
				}
				
				if (is_array($filter['fields'])) {
					$fields = array();
					foreach ($filter['fields'] as $field) {
						$fields[] = array($field, $data);
					}
					$collection->addFieldToFilter($fields);
				} else {
					$collection->addFieldToFilter($filter['fields'], $data);
				}
			}
		}
		
		if ($this->grids['sort']['field']) {
			$collection->setOrder($this->grids['sort']['field'], $this->grids['sort']['order']);
		}
		$paginator->setDefaultItemCountPerPage($this->grids['pager']['size']);
		$paginator->setCurrentPageNumber($this->grids['pager']['page']);
	}

	/**
	 * 
	 * @param Evebit_Model_Mysql_Collection $collection
	 * 
	 */
	public function getPaginator($collection, $id = "default", $filters = array(), $orders = array(), $default = array()) {
		/* start init */
		$controller = Zend_Controller_Front::getInstance();
		$request = $controller->getRequest();
		
		if (!(is_array(@$this->page[$id]))) {
			$this->page[$id] = array(
					'id'=> $id, 
					'filters'=> array(), 
					'orders'=> array(), 
					'sort'=> array(
							'key'=> null, 
							'field'=> isset($default['sort']) ? $orders[$default['sort']] : null, 
							'order'=> isset($default['order']) && $default['order'] == 'desc' ? 'desc' : 'asc'), 
					'pager'=> array(
							'size'=> isset($default['size']) ? $default['size'] : 12, 
							'page'=> 1));
		}
		
		if ($filters) {
			$data = $request->getParam('filter');
			foreach ($filters as $key => $filter) {
				$fields = $filter['fields'];
				$type = $filter['type'];
				if (!isset($this->page[$id]['filters'][$key])) {
					$this->page[$id]['filters'][$key] = array(
							'key'=> $key, 
							'fields'=> $fields, 
							'type'=> $type, 
							'data'=> null);
				}
				if (isset($data[$key])) {
					$val = $data[$key];
					switch ($type) {
						case 'int' :
							if (!@$val['from']) {
								unset($val['from']);
							}
							if (!@$val['to']) {
								unset($val['to']);
							}
							if (!$val) {
								$val = null;
							}
							break;
						case 'string' :
							if (isset($val['like']) && !@$val['like']) {
								$val = null;
							}
							break;
					}
					$this->page[$id]['filters'][$key]['data'] = $val;
				}
			}
		}
		
		if ($orders) {
			$data = array('key'=> $request->getParam('sort'), 'order'=> $request->getParam('order'));
			if ($data && isset($orders[$data['key']])) {
				$data['field'] = $orders[$data['key']];
				$this->page[$id]['sort'] = $data;
			}
			$this->page[$id]['orders'] = $orders;
		}
		
		$data = intval($request->getParam('PerPage'));
		if ($data) {
			$this->page[$id]['pager']['size'] = $data;
		}
		
		$data = intval($request->getParam('page'));
		if ($data) {
			$this->page[$id]['pager']['page'] = $data;
		}
		/* end init */
		
		$adapter = new Evebit_Model_Paginator_Adapter($collection);
		$paginator = new Zend_Paginator($adapter);
		foreach ($this->page[$id]['filters'] as $filter) {
			if ($filter['data']) {
				if (is_array($filter['data'])) {
					$data = $filter['data'];
				} else {
					$data = array('eq'=> $filter['data']);
				}
				
				if (isset($data['like'])) {
					$data['like'] = '%' . $data['like'] . '%';
				}
				if (isset($data['nlike'])) {
					$data['nlike'] = '%' . $data['nlike'] . '%';
				}
				
				if (is_array($filter['fields'])) {
					$fields = array();
					foreach ($filter['fields'] as $field) {
						$fields[] = array($field, $data);
					}
					$collection->addFieldToFilter($fields);
				} else {
					$collection->addFieldToFilter($filter['fields'], $data);
				}
			}
		}
		
		if ($this->page[$id]['sort']['field']) {
			$collection->setOrder($this->page[$id]['sort']['field'], 
				$this->page[$id]['sort']['order']);
		}
		
		$paginator->setDefaultItemCountPerPage($this->page[$id]['pager']['size']);
		$paginator->setCurrentPageNumber($this->page[$id]['pager']['page']);
		
		$paginator->pageState = $this->getPageState($id);
		return $paginator;
	}

	/**
	 * reset page filters
	 */
	public function resetPage($id) {
		$this->page[$id] = null;
	}

	/**
	 * fetch page state 
	 */
	public function getPageState($id) {
		return $this->page[$id];
	}

	/**
	 * @param $name string 
	 * 
	 * */
	
	public function getFormParam($name, $default = '', $nameSpace = '') {
		$controller = Zend_Controller_Front::getInstance();
		$request = $controller->getRequest();
		$value = $request->getParam($name, $default);
		if ($request->getParam($name) === null) {
			$value = $this->__get($nameSpace . $name);
			if ($value) {
				return $value;
			} else {
				return $default;
			}
		} else {
			$this->__set($nameSpace . $name, $value);
			return $value;
		}
	}
	
	

	/**
	 * getGoogleClient
	 * 
	 * */
	
	public function getGoogleClient(){
		if($this->client)
		return $this->client;
		else 
		return null;
    }
    /**
	 * getRefreshGoogleKey
	 * 
	 * */
    public function getRefreshGoogleKey(){
    	if($this->refreshGoogleKey)
		return $this->refreshGoogleKey;
		else 
		return null;
    }
    
    /**
	 * Refresh the google cilent
	 * @param $refreshKey string
	 * */
    
    public function refreshGoogleClient($refreshKey){
    	$clientId=Zend_Registry::get("clientId");
		$redirectUri=Zend_Registry::get("redirectUri");
		$clientSecret=Zend_Registry::get("clientSecret");
		$cilent=new Zend_Http_Client("https://accounts.google.com/o/oauth2/token");
		$cilent->setMethod(Zend_Http_Client::POST);
		$cilent->setEncType("application/x-www-form-urlencoded");
		$cilent->setParameterPost("refresh_token",$refreshKey);
		$cilent->setParameterPost("client_id",$clientId);
		$cilent->setParameterPost("client_secret",$clientSecret);
		$cilent->setParameterPost("grant_type","refresh_token");
		$response = $cilent->request();
		$jsonResponse=Zend_Json::decode($response->getRawBody(), Zend_Json::TYPE_ARRAY);
	    $accessKey=$jsonResponse["access_token"];
	    $client =Zend_Gdata_AuthSub::getHttpClient($accessKey);
	    $this->client=$client;
    }
    
 	/**
 	 * google client login captcha
 	 * @param string $gmail
 	 * @param string $password
 	 * @param string $service
 	 * @param string $appName
 	 * @param string $checkCode
 	 * @param string $captcha
 	 * @return object|bool
 	 */
    public function googleClientLoginCaptcha($gmail, $password ,$service,$appName,$checkCode,$captcha){
    	$return = '';
    	$catch = Zend_Registry::get('clientLoginCatch');
    	try {
    		$this->imgUrl = '';
			$this->token = '';
			$client = Zend_Gdata_ClientLogin::getHttpClient($gmail, $password ,$service,null,$appName,$checkCode,$captcha);
		} catch (Zend_Gdata_App_CaptchaRequiredException $cre) {
			if($catch) {
				$this->addError('Please checke your username and passwork,enter the checkcode,then try again');
				$this->imgUrl= $cre->getCaptchaUrl();
				$this->token = $cre->getCaptchaToken();
			} else {
				$return = true;
			}
		} catch (Zend_Gdata_App_AuthException $ae) {
			$this->addMessage($ae->getTraceAsString());
		 	$this->addError('Login fail,please check your username and password,then try again');
		} catch (Zend_Gdata_App_Exception $ze) {
			if($catch) {
				$this->addError('There is something wrong with the network,unable to Connect to ssl://www.google.com:443');
			} else {
				$return = true;
			}
		} catch (Zend_Gdata_App_HttpException $he) {
			echo $he->getTraceAsString();
			$this->addError($this->__('Login fail,please check your username and password,then try again'));
		}
		if(isset($client)) {
			$return = $client;
		} else {
			$return = false;
		}
		return $return;
    }
    
    /**
	 * get a google clandar feed object
	 * 
	 * */
    public function getGoogleClandarListFeed(){
    	if(!$this->clandarListFeed){
    	$client=$this->getGoogleClient();
		try {
			$gdataCal = new Zend_Gdata_Calendar($client);
			$calFeed = $gdataCal->getCalendarListFeed();
		} catch (Exception $e) {
			if(strstr($e->getMessage(), "Unable to Connect to ssl://www.google.com:443")){
				return "unable to connect";
			}
			$refreshKey=$this->getRefreshGoogleKey();
			$this->refreshGoogleClient($refreshKey);
			$gdataCal = new Zend_Gdata_Calendar($this->getGoogleClient());
			$calFeed = $gdataCal->getCalendarListFeed();
		}
		$this->clandarListFeed=$calFeed;
		return $calFeed;
    	}
    	else {
    	return $this->clandarListFeed;
    	}
		
    }
    
     /**
	 * get a google clandar event object
	 * 
	 * */
	public function getGoogleClandarEvent(){
    	if(!$this->clandarEvent){
    	$client=$this->getGoogleClient();
		try {
			$gdataCal = new Zend_Gdata_Calendar($client);
			$eventFeed = $gdataCal->getCalendarEventFeed();
			
		} catch (Exception $e) {
			if(strstr($e->getMessage(), "Unable to Connect to ssl://www.google.com:443")){
				return "unable to connect";
			}
			$refreshKey=$this->getRefreshGoogleKey();
			$this->refreshGoogleClient($refreshKey);
			$gdataCal = new Zend_Gdata_Calendar($this->getGoogleClient());
			$eventFeed = $gdataCal->getCalendarEventFeed();
		}
		$this->clandarEvent=$eventFeed;
		return $eventFeed;
    	}
    	else {
    	return $this->clandarEvent;
    	}
		
    }
    
    /**
	 * clean up all google session
	 * 
	 * */
    public function cleanGoogleSession(){
    	unset($this->client);
    	unset($this->clandarEvent);
    	unset($this->clandarListFeed);
    }
    
}

